package com.ybkj.daijia.server;


import com.ybkj.daijia.server.event.model.OrderPaidanEvent;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.Order;
import com.ybkj.daijia.server.scheduler.ThreadControl;
import com.ybkj.daijia.server.service.DriverService;
import com.ybkj.daijia.server.service.OrderRefuseRecordService;
import com.ybkj.daijia.server.service.OrderService;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.util.CollectionUtils;

public class OrderTimerTask extends TimerTask {

    private ApplicationEventMulticaster applicationEventMulticaster;

    /**
     * 第一阶段自动派单距离
     */
    private Double autoPaidanKm1;
    /**
     * 第一阶段自动派单时间
     */
    private Integer autoPaidanTime1;
    /**
     * 第二阶段自动派单距离
     */
    private Double autoPaidanKm2;
    /**
     * 第二阶段自动派单时间
     */
    private Integer autoPaidanTime2;
    /**
     * 第三阶段自动派单距离
     */
    private Double autoPaidanKm3;
    /**
     * 第三阶段自动派单时间
     */
    private Integer autoPaidanTime3;

    private Long orderId;

    private Double longitude;

    private Double latitude;

    private int setup;

    public OrderTimerTask(
        Double autoPaidanKm1, Integer autoPaidanTime1,
        Double autoPaidanKm2, Integer autoPaidanTime2,
        Double autoPaidanKm3, Integer autoPaidanTime3,
        ApplicationEventMulticaster applicationEventMulticaster,
        Long orderId, Double latitude, Double longitude, int setup) {

        this.autoPaidanKm1 = autoPaidanKm1;
        this.autoPaidanTime1 = autoPaidanTime1;
        this.autoPaidanKm2 = autoPaidanKm2;
        this.autoPaidanTime2 = autoPaidanTime2;
        this.autoPaidanKm3 = autoPaidanKm3;
        this.autoPaidanTime3 = autoPaidanTime3;
        this.applicationEventMulticaster = applicationEventMulticaster;

        this.orderId = orderId;
        this.latitude = latitude;
        this.longitude = longitude;
        this.setup = setup;
    }


    @Override
    public void run() {

        if (isEmpty()) {

            cancelTask(this);

        } else {

            OrderService orderService = Config.getWac().getBean(OrderService.class);

            Order order = orderService.findOne(orderId);

            if (null == order || !order.getStatus().equals(Order.ORDER_STATUS_NEW)) {

                cancelTask(this);

            } else if ((System.currentTimeMillis() - order.getServerTime().getTime())
                >= 2 * 60 * 60 * 1000) {

                cancelTask(this);

            } else {
                DriverService driverService = Config.getWac().getBean(DriverService.class);
                OrderRefuseRecordService orderRefuseRecordService = Config.getWac()
                    .getBean(OrderRefuseRecordService.class);

                if (setup == 1) {//第一阶段查询
                    if (ThreadControl.SysAutoRunning) {
                        List<Driver> drivers = driverService
                            .queryPaidanTuijian(longitude, latitude, autoPaidanKm1);
                        if (CollectionUtils.isEmpty(drivers)) {
                            //失败 进行第二阶段
                            cancelAndNextTask(this, 2);
                        } else {

//							Driver thisDriver=drivers.get((int)(Math.random()*drivers.size()));

                            Driver thisDriver = null;
                            for (Driver driver : drivers) {
                                Long refuseRecord = orderRefuseRecordService
                                    .findExists(driver.getId(), order.getId());
                                if (refuseRecord == 0) {
                                    thisDriver = driver;
                                    break;
                                }
                            }

                            if (null == thisDriver) {
                                //司机已拒绝过该工单
                                cancelAndNextTask(this, 2);

                            } else {
                                int result = orderService.autoPaidan(thisDriver, order);

                                if (result == 1) {//派单成功
                                    cancelTask(this);
                                    //派单事件
                                    OrderPaidanEvent paidanEvent = new OrderPaidanEvent(order);
                                    applicationEventMulticaster.multicastEvent(paidanEvent);
                                } else {
                                    atOnceCancelAndPaidan(this, 1);
                                }
                            }

                        }
                    } else {

                        cancelAndNextTask(this, 2);

                    }

                } else if (setup == 2) {//第二阶段查询
                    if (ThreadControl.SysAutoRunning) {
                        List<Driver> drivers = driverService
                            .queryPaidanTuijian(longitude, latitude, autoPaidanKm2);
                        if (CollectionUtils.isEmpty(drivers)) {
                            //失败 循环进行第三阶段

                            cancelAndNextTask(this, 3);

                        } else {

//							Driver thisDriver=drivers.get((int)(Math.random()*drivers.size()));

                            Driver thisDriver = null;
                            for (Driver driver : drivers) {
                                Long refuseRecord = orderRefuseRecordService
                                    .findExists(driver.getId(), order.getId());
                                if (refuseRecord == 0) {
                                    thisDriver = driver;
                                    break;
                                }
                            }

                            if (null == thisDriver) {
                                //司机已拒绝过该工单

                                cancelAndNextTask(this, 3);

                            } else {
                                int result = orderService.autoPaidan(thisDriver, order);

                                if (result == 1) {//派单成功
                                    cancelTask(this);
                                    //派单事件
                                    OrderPaidanEvent paidanEvent = new OrderPaidanEvent(order);
                                    applicationEventMulticaster.multicastEvent(paidanEvent);
                                } else {
                                    atOnceCancelAndPaidan(this, 2);
                                }
                            }

                        }
                    } else {

                        cancelAndNextTask(this, 3);

                    }

                } else if (setup == 3) {//第三阶段查询
                    if (ThreadControl.SysAutoRunning) {
                        List<Driver> drivers = driverService
                            .queryPaidanTuijian(longitude, latitude, autoPaidanKm3);

                        Driver thisDriver = null;
                        if (!CollectionUtils.isEmpty(drivers)) {
                            for (Driver driver : drivers) {
                                Long refuseRecord = orderRefuseRecordService
                                    .findExists(driver.getId(), order.getId());
                                if (refuseRecord == 0) {
                                    thisDriver = driver;
                                    break;
                                }
                            }
                        }

                        if (null != thisDriver) {

                            Long refuseRecord = orderRefuseRecordService
                                .findExists(thisDriver.getId(), order.getId());
                            if (null == refuseRecord || refuseRecord == 0) {
                                int result = orderService.autoPaidan(thisDriver, order);

                                if (result == 1) {//派单成功
                                    cancelTask(this);
                                    //派单事件
                                    OrderPaidanEvent paidanEvent = new OrderPaidanEvent(order);
                                    applicationEventMulticaster.multicastEvent(paidanEvent);
                                }
                            }

                        }
                    }
                }
            }
        }

    }


    private void atOnceCancelAndPaidan(OrderTimerTask orderTimerTask, int step) {

        try {
            orderTimerTask.cancel();
            ThreadControl.TaskMaps.remove("task_" + orderId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Timer timer = new Timer();

        if (step == 1) {
            timer.schedule(new OrderTimerTask(
                autoPaidanKm1, autoPaidanTime1,
                autoPaidanKm2, autoPaidanTime2,
                autoPaidanKm3, autoPaidanTime3,
                applicationEventMulticaster,
                orderId, latitude, longitude, step), 0);
            ThreadControl.TaskMaps.put("task_" + orderId, timer);
        } else if (step == 2) {
            timer.schedule(new OrderTimerTask(
                autoPaidanKm1, autoPaidanTime1,
                autoPaidanKm2, autoPaidanTime2,
                autoPaidanKm3, autoPaidanTime3,
                applicationEventMulticaster,
                orderId, latitude, longitude, step), 0);
            ThreadControl.TaskMaps.put("task_" + orderId, timer);
        } else if (step == 3) {
            timer.schedule(new OrderTimerTask(
                autoPaidanKm1, autoPaidanTime1,
                autoPaidanKm2, autoPaidanTime2,
                autoPaidanKm3, autoPaidanTime3,
                applicationEventMulticaster,
                orderId, latitude, longitude, step), 0);
            ThreadControl.TaskMaps.put("task_" + orderId, timer);
        }

    }


    private void cancelTask(OrderTimerTask orderTimerTask) {

        try {
            orderTimerTask.cancel();
            ThreadControl.TaskMaps.remove("task_" + orderId);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void cancelAndNextTask(OrderTimerTask orderTimerTask, int step) {

        try {
            orderTimerTask.cancel();
            ThreadControl.TaskMaps.remove("task_" + orderId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Timer timer = new Timer();

        if (step == 2) {
            timer.schedule(new OrderTimerTask(
                autoPaidanKm1, autoPaidanTime1,
                autoPaidanKm2, autoPaidanTime2,
                autoPaidanKm3, autoPaidanTime3,
                applicationEventMulticaster,
                orderId, latitude, longitude, step), autoPaidanTime2 * 1000);
            ThreadControl.TaskMaps.put("task_" + orderId, timer);
        } else if (step == 3) {
            timer.schedule(new OrderTimerTask(
                    autoPaidanKm1, autoPaidanTime1,
                    autoPaidanKm2, autoPaidanTime2,
                    autoPaidanKm3, autoPaidanTime3,
                    applicationEventMulticaster,
                    orderId, latitude, longitude, step), autoPaidanTime3 * 1000,
                autoPaidanTime3 * 1000);
            ThreadControl.TaskMaps.put("task_" + orderId, timer);
        }

    }

    private boolean isEmpty() {
        if (autoPaidanKm1 == null || autoPaidanTime1 == null ||
            autoPaidanKm2 == null || autoPaidanTime2 == null ||
            autoPaidanKm3 == null || autoPaidanTime3 == null ||
            orderId == null || longitude == null || latitude == null) {
            return true;
        }
        return false;
    }


}

